#pragma once 
#include <iostream>
#include "sock.hpp"
#include <sys/epoll.h>

namespace my_epoll
{
  class Epoll
  {
    private:
      int listen_sock;
      unsigned short port;
      int epfd;
    public:
      Epoll(unsigned short _port):port(_port)
     {}
      ~Epoll()
      {
        if(listen_sock>0)
        close(listen_sock);
        if(epfd>0)
        close(epfd);
      }
    public:
      void InitEopll()
      {
        listen_sock=my_sock::Sock::Socket();
        my_sock::Sock::Bind(listen_sock,port);
        my_sock::Sock::Listen(listen_sock,5);
        epfd=epoll_create(256);
        if(epfd<0)
        {
          std::cerr<<"epoll_create error"<<std::endl;
          exit(5);
        }
        
      }
      void AddEpoll(int sock,uint32_t events)
      {
        struct epoll_event ev;
        ev.events=0;
        ev.events |= events;//非必须，这里可以同时 读 与 写
       ev.data.fd=sock; 
        if(epoll_ctl(epfd,EPOLL_CTL_ADD,sock,&ev)<0)
        {
          std::cerr<<"epoll_ctl error"<<std::endl;
        }
      }
      void EdlEpoll(int sock)
      {
        epoll_ctl(epfd,EPOLL_CTL_DEL,sock,nullptr);
        std::cout<<sock<<"退出 "<<std::endl;
      }
      void Run()
      {
        AddEpoll(listen_sock,EPOLLIN);
        struct epoll_event resv[64];
        int timeout=1000;
        while(1)
        {
          int num=epoll_wait(epfd,resv,64,timeout);
            if(num>0)
            {
              for(int i=0;i<num;i++)
              {
                if(resv[i].events & EPOLLIN)
                {
                  if(resv[i].data.fd==listen_sock)//添加连接
                  {
                    struct sockaddr_in perr;
                    socklen_t size=sizeof(perr);
                    int sock=accept(listen_sock,(struct sockaddr*)&perr,&size);
                    if(sock<0)
                    {
                      std::cerr<<"accept error"<<std::endl;
                    }
                    AddEpoll(sock,EPOLLIN);
                  }else
                  {
                    char buffer[1024];
                    int s=recv(resv[i].data.fd,buffer,sizeof(buffer)-1,0);
                    if(s>0)
                    {
                      buffer[s]=0;
                      std::cout<<buffer<<std::endl;
                    }else 
                    {
                      std::cout<<"连接 退出"<<std::endl;
                      close(resv[i].data.fd );
                      EdlEpoll(resv[i].data.fd);
                    }
                  }   
                }else if(resv[i].events & EPOLLOUT)//写事件
                {

                }else 
                {

                }
              }//for num 
            }else if(num==0)
            {
              std::cout<<"timeout:"<<timeout<<std::endl;
            }else 
            {
              std::cerr<<" epoll_wait error"<<std::endl;
            }//e_w if 
        }//while
      }

  };
}















